package com.frame.auth.mvc.web;

import com.frame.auth.mvc.dao.pojo.vo.TokenVO;
import com.frame.auth.security.exception.AuthResponseException;
import com.frame.common.tools.result.ServiceResult;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.endpoint.CheckTokenEndpoint;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.security.Principal;
import java.util.Map;

/**
 * @auther zhangwj
 * @date 2021/3/30 下午4:17
 */
@RestController
@RequestMapping(value = "oauth")
public class OAuthController {

    private final WebResponseExceptionTranslator<OAuth2Exception> exceptionTranslator = new AuthResponseException();

    @Resource
    private TokenEndpoint tokenEndpoint;

    @Resource
    private CheckTokenEndpoint checkTokenEndpoint;

    @GetMapping("token")
    public ServiceResult<Object> getAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        ResponseEntity<OAuth2AccessToken> responseEntity = tokenEndpoint.getAccessToken(principal, parameters);
        return ServiceResult.getSuccessResult(getToken(responseEntity));
    }

    @PostMapping("token")
    public ServiceResult<TokenVO> postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        ResponseEntity<OAuth2AccessToken> responseEntity = tokenEndpoint.postAccessToken(principal, parameters);
        return ServiceResult.getSuccessResult(getToken(responseEntity));
    }

    @PostMapping("check_token")
    public Map<String, ?> checkToken(@RequestParam("token") String value) {
        return checkTokenEndpoint.checkToken(value);
    }

    @ExceptionHandler({Exception.class})
    public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
        return this.exceptionTranslator.translate(e);
    }

    private TokenVO getToken(ResponseEntity<OAuth2AccessToken> responseEntity) {
        if (null != responseEntity) {
            OAuth2AccessToken oAuth2AccessToken = responseEntity.getBody();
            if (null != oAuth2AccessToken) {
                TokenVO tokenVO = new TokenVO();
                tokenVO.setAccess_token(oAuth2AccessToken.getValue());
                OAuth2RefreshToken oAuth2RefreshToken = oAuth2AccessToken.getRefreshToken();
                if (null != oAuth2RefreshToken) {
                    tokenVO.setRefresh_token(oAuth2RefreshToken.getValue());
                }
                tokenVO.setExpires_in(oAuth2AccessToken.getExpiresIn());
                tokenVO.setToken_type(oAuth2AccessToken.getTokenType());
                return tokenVO;
            }
        }
        return null;
    }
}
